using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using App.Controlador;
using App.Modelo;
using App.Modelo.Interfaces;
using App.SolInf.Controlador;
using App.SolInf.Modelo;
using App.Persistencia;

namespace App.Instalador
{
    class SolInfInstaladorDatos
    {
        public void InstalarDatosSeguridad(IRepositorio dbh, string[] permisos)
        {
            // inserto los grupos
            dbh.SaveObject(new Funcion("modificar"));

            var grupos = new ControladoraGrupos {Repositorio = dbh};
            var perfiles = new ControladoraPerfiles {Repositorio = dbh};
            var usuarios = new ControladoraUsuarios {Repositorio = dbh};



            Grupo Administradores = grupos.Create(new Grupo("Administradores"), permisos, true);

            Administradores = grupos.Get(Administradores);
            var vendedores = new Grupo("Vendedor");
            var compras = new Grupo("Jefe de compras");

            dbh.SaveObject(new Grupo("Usuario"));
            dbh.SaveObject(vendedores);
            dbh.SaveObject(compras);
            dbh.SaveObject(new Grupo("Supervisor"));
            dbh.SaveObject(new Grupo("Otro"));

            perfiles.GrantAll(Administradores);

            var admin = usuarios.Alta(Administradores, "11548887",
                                                    "admin", "admin", "asd", "admin");
            admin.Grupos.Add(vendedores);
            admin.Grupos.Add(compras);
            

            usuarios.Alta(vendedores, "123456789", "Filidoro", "Gustavo", "asd", "fili");
            usuarios.Alta(compras, "987656415", "Masias", "Mariana", "asd", "mari");

        }

        public void InstalarDatosDemo(IRepositorio dbh)
        {
            var usuarios = dbh.GetAll<App.Modelo.Usuario>();
            var usuario = usuarios.First();

            // clientes 
            var Cli1 = new Cliente
            {
                RazonSocial = "Tux Solutions",
                Domicilio = new Domicilio
                {
                    Calle = "9 de julio",
                    Numero = "639",
                    Departamento = "A",
                    Localidad = new Ubicacion("Rosario", "2700", "Rosario", "Argentina")
                },
                Email = "tux@tux.com",
                Documento = new Documento("CUIT", "23-315422111-9"),
                Telefono1 = "0341 3154222",
            };

            var Cli2 = new Cliente
            {
                RazonSocial = "La Perla SA",
                Domicilio = new Domicilio
                {
                    Calle = "Paraguay",
                    Numero = "1456",
                    Piso = "7",
                    Departamento = "C",
                    Localidad = new Ubicacion("Rosario", "2000", "Santa Fe", "Argentina")
                },
                Email = "laperla@hotmail.com",
                Documento = new Documento("CUIT", "23-33322111-9"),
                Telefono1 = "0341 3223322",
            };


            var micros = new CategoriaProducto("Microprocesadores");
            var intel = new Marca("Intel");
            var amd = new Marca("AMD");
            var pentiumII = new Producto()
            {
                Categoria = micros,
                Marca = intel,
                Descripcion = "Intel Pentium II 450Mhz",
                Costo = 89.50,
                Ganancia = 1.5
            };
            var pres1 = new Presupuesto()
            {
                Cliente = Cli1,
                FechaAlta = DateTime.Now,
                Vendedor = usuario,
                LineasPresupuesto = new List<LineaPresupuesto>()
                                                        {
                                                            new LineaPresupuesto()
                                                                {
                                                                    Producto = pentiumII,
                                                                    Cantidad = 2,
                                                                    PrecioUnitario = pentiumII.Precio
                                                                }
                                                        }
            };

            dbh.SaveObject(micros);
            dbh.SaveObject(intel);
            dbh.SaveObject(amd);

            var marcas = from nom in _read("datos/marcas.txt")
                         select new Marca() { Descripcion = nom[0] };

            var categorias = from nom in _read("datos/categorias.txt")
                             select new CategoriaProducto() { Descripcion = nom[0] };

            var productos = _getProcesadores(micros, amd, intel);

            foreach (var marca in marcas) 
                dbh.SaveObject(marca);
            foreach (var categoriaProducto in categorias) 
                dbh.SaveObject(categoriaProducto);

            foreach (var c in _getClientes())
                dbh.SaveObject(c);
            foreach (var p in _getProveedores())
                dbh.SaveObject(p);

            foreach (var pro in productos) 
                dbh.SaveObject(pro);


            dbh.SaveObject(Cli1);
            dbh.SaveObject(Cli2);
            dbh.SaveObject(pentiumII);
            dbh.SaveObject(pres1);

            
            var proveedores = dbh.GetAll<Proveedor>();

            dbh.SaveObject(new Movimiento()
            {
                Empleado = usuarios.GetRandom(),
                Fecha = DateTime.Now.Subtract(new TimeSpan(60, 0, 0, 0)),
                Detalle = new Compra()
                {
                    Proveedor = proveedores.GetRandom(),
                    Lineas = new List<LineaCompra>()
                                                                  {
                                                                      new LineaCompra(productos.GetRandom(), 3, 120),
                                                                      new LineaCompra(productos.GetRandom(), 14, 123),
                                                                      new LineaCompra(productos.GetRandom(), 15, 327),
                                                                      new LineaCompra(productos.GetRandom(), 7, 85)
                                                                  }
                },
                Comentario = "Compra de procesadores",

                Lineas = new List<LineaMovimiento>()
                                                {
                                                    new LineaMovimiento(productos.GetRandom(), 3),
                                                    new LineaMovimiento(productos.GetRandom(), 14),
                                                    new LineaMovimiento(productos.GetRandom(), 15),
                                                    new LineaMovimiento(productos.GetRandom(), 7)
                                                }
            });

            dbh.SaveObject(new Movimiento()
            {
                Empleado = usuarios.GetRandom(),
                Fecha = DateTime.Now.Subtract(new TimeSpan(40, 0, 0, 0)),
                Comentario = "Compra de 100 procesadores",
                Detalle = new AjusteStock()
                {
                    Motivo = "Ajuste inicial del stock",

                    Documentacion = new Documentacion()
                    {
                        Fecha =
                            DateTime.Now.Subtract(new TimeSpan(10,
                                                               0, 0,
                                                               0)),
                        Numero = "0001-00108922",
                        Tipo = TipoDocumentacion.Factura
                    },
                },
                Lineas = new List<LineaMovimiento>()
                                                {
                                                    new LineaMovimiento(productos.GetRandom(), 20),
                                                    new LineaMovimiento(productos.GetRandom(), 10),
                                                    new LineaMovimiento(productos.GetRandom(), 15)
                                                }
            });

            dbh.SaveObject(new Movimiento()
            {
                Empleado = usuarios.GetRandom(),
                Detalle = new Compra()
                {
                    Documentacion = new Documentacion()
                    {
                        Fecha =
                            DateTime.Now.Subtract(new TimeSpan(15,
                                                               0, 0,
                                                               0)),
                        Numero = "0001-00101009",
                        Tipo = TipoDocumentacion.Remito
                    },
                    Proveedor = proveedores.GetRandom()
                },
                Fecha = DateTime.Now.Subtract(new TimeSpan(50, 0, 0, 0)),
                Comentario = "Compra de procesadores",

                Lineas = new List<LineaMovimiento>()
                                                {
                                                    new LineaMovimiento(productos.GetRandom(), 3),
                                                    new LineaMovimiento(productos.GetRandom(), 12),
                                                    new LineaMovimiento(productos.GetRandom(), 15),
                                                    new LineaMovimiento(productos.GetRandom(), 7)
                                                }
            });


        }

        private List<string[]> _read(string path)
        {
            var descripciones = new List<string[]>();
            using (var readFile = new StreamReader(path))
            {
                // excluyo la primera fila
                var line = readFile.ReadLine();

                while ((line = readFile.ReadLine()) != null)
                {
                    var arr = (from s in line.Split('\t') 
                               select s.Trim()).ToArray();
                    if (arr.Any(st => ! String.IsNullOrEmpty(st)))
                        descripciones.Add(arr);    
                }
            }
            return descripciones;
        }
        private Cliente[] _getClientes()
        {

            return (from d in _read("datos/clientes.txt")
                    select new Cliente()
                    {
                        RazonSocial = d[0],
                        Contacto = d[1],
                        Domicilio = new Domicilio()
                        {
                            Calle = d[2],
                            Localidad = new Ubicacion
                            {
                                Localidad = d[5],
                                Provincia = d[6],
                                CodPostal = d[7],
                            }
                        },
                        Telefono1 = d[3],
                        Email = d[4],
                        Documento = new Documento("CUIT", d[8])
                    }).ToArray();
        }
        private Proveedor[] _getProveedores()
        {

            return (from d in _read("datos/proveedores.txt")
                    select new Proveedor()
                    {
                        RazonSocial = d[0],
                        Contacto = d[1],
                        Domicilio = new Domicilio()
                        {
                            Calle = d[2],
                            Localidad = new Ubicacion
                            {
                                Localidad = d[5],
                                Provincia = d[6],
                                CodPostal = d[7],
                            }
                        },
                        Telefono1 = d[3],
                        Email = d[4],
                        Documento = new Documento("CUIT", d[8])
                    }).ToArray();
        }

        private Producto[] _getProcesadores(CategoriaProducto micros, Marca amd, Marca intel)
        {
            var descripciones = _read("datos/procesadores.txt");

            var rnd = new Random();
            return (from s in descripciones
                    select new Producto()
                    {
                        Descripcion = s[0].Trim(),
                        Marca = s[0].Contains("AMD") ? amd : intel,
                        Costo = Math.Round(rnd.NextDouble() * 100, 2),
                        Ganancia = 1.5,
                        Categoria = micros,
                        StockMinimo = 3,
                        StockMaximo = 10
                    }
                   ).ToArray();

        }
    }
}
